/* 
 * File:   fctions.c
 * Author: rslmanu
 *
 * Created on 18 mai 2009, 15:39
 */

/*
Copyright (C) 2009 Roussel Emmanuel

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "fctions.h"


//------------------------------------------------------------------------------

int read_char() { //lit un caractère entré au clavier, sans bloquer le programme. Renvoie le code correspondant au caractère.
    unsigned char c;
    int ret = read(STDIN_FILENO, &c, 1); // Lit un caractère sur l'entrée standard

    switch (ret) {
        case -1 : //aucune touche appuiée
            return -1;
        case 0: //error
            return -2;
        default: //une touche est appuiée
            return c;
    }
}

void print_map() { //update the drawings.
    int i,j;

    CLS();
    for (i = 0; i < OFFSET_Y; i++)
        printf("\n");
    for (i = 0; i < OFFSET_X; i++)
            printf(" ");
    for (i = 0; i < TAILLE_X; i++)
        printf("-");
    printf("\n");

    for (i = 0; i < TAILLE_Y; i++){
        for (j = 0; j < OFFSET_X; j++)
            printf(" ");
        printf("|");
        for (j = 0; j < TAILLE_X-2; j++)
            printf(" ");
        printf("|\n");
    }
    
    for (i = 0; i < OFFSET_X; i++)
            printf(" ");
    for (i = 0; i < TAILLE_X; i++)
        printf("-");
    printf("\n");
    UPD();
}

void update_serpent(bout **serpent, int dir) { //update the position of the snake
    bout *bout_end = NULL;

    //ajoute un bout de serpent dans la bonne direction
    if (dir == NORD)
        if(((*serpent)->y - 1) > OFFSET_Y -1)  
            ll_push(serpent, (*serpent)->x, (*serpent)->y - 1);
        else            //si on rentre dans un bord, le serpent passe de l'autre coté
            ll_push(serpent, (*serpent)->x, OFFSET_Y + TAILLE_Y -1);
    else if (dir == SUD)
        if(((*serpent)->y + 1) < OFFSET_Y + TAILLE_Y)
            ll_push(serpent, (*serpent)->x, (*serpent)->y + 1);
        else
            ll_push(serpent, (*serpent)->x, OFFSET_Y);
    else if (dir == EST)
        if(((*serpent)->x +1) < OFFSET_X + TAILLE_X)
            ll_push(serpent, (*serpent)->x +1, (*serpent)->y);
        else
            ll_push(serpent, OFFSET_X+2, (*serpent)->y);
    else if (dir == OUEST)
        if(((*serpent)->x -1) > OFFSET_X+1)
            ll_push(serpent, (*serpent)->x -1, (*serpent)->y);
        else
            ll_push(serpent, OFFSET_X + TAILLE_X-1, (*serpent)->y);

    ll_pop_end(serpent); //suppr le bout de serpent de la fin.

    CURSEUR((*serpent)->x, (*serpent)->y);
    printf("@");
    bout_end = ll_return_last(*serpent);
    CURSEUR(bout_end->x, bout_end->y);
    printf(" ");
    UPD();
}

void update_pomme(bout **p, pomme *pom){
    bout *serpent = *p;
    bout *last = ll_return_last(serpent);
    if(pom->pomme_in_progress){
        if(ll_exist(serpent, pom->pomme_x, pom->pomme_y)){  //la pomme est mangée !
            CURSEUR(pom->pomme_x, pom->pomme_y);
            printf("@");
            UPD();
            pom->pomme_in_progress = 0;
            ll_push_end(&serpent, last->x, last->y);  //rajoute un bout au serpent !
            ll_push_end(&serpent, last->x, last->y);  //rajoute un bout au serpent !
        }
    }
    if(!(pom->pomme_in_progress)){
        pom->pomme_x = pif(OFFSET_X+2, TAILLE_X+OFFSET_X);
        pom->pomme_y = pif(OFFSET_Y, TAILLE_Y+OFFSET_Y);
        if(!ll_exist(serpent, pom->pomme_x, pom->pomme_y)){   //si le serpent est pas sur la pomme
            CURSEUR(pom->pomme_x, pom->pomme_y);
            printf("&");
            pom->pomme_in_progress = 1;
            UPD();
        }
    }
}

int check_perdu(bout *serpent){
    return ll_exist(serpent->suiv, serpent->x, serpent->y);   //si la tète rentre dans le corps => perdu
}


int pif(int min, int max){  //return une valeur between min et max !
    return (int)(min + rand()%(max-min));
}


//------------------------------------------------------------------------------

// modif du fctionnement par défault du terminal (pour eviter d'attendre l'appui sur entrée pour valider)
//saisie non canonique + echo off

int reconfigure_terminal(struct termios *prev) {
    struct termios tios2;
    int fd = 0;
    int mode;

    if (tcgetattr(fileno(stdin), prev) == -1) {
        perror("tcgetattr");
        return -1;
    }
    tios2.c_iflag = prev->c_iflag;
    tios2.c_oflag = prev->c_oflag;
    tios2.c_cflag = prev->c_cflag;
    tios2.c_lflag = 0;
    tios2.c_cc[VMIN] = 1;
    tios2.c_cc[VTIME] = 0;
    if (tcsetattr(fileno(stdin), TCSANOW, &tios2) == -1) {
        perror("tcsetattr");
        return -1;
    }

    mode = fcntl(fd, F_GETFL, 0);
    mode |= O_NONBLOCK;
    fcntl(fd, F_SETFL, mode);

    //(pr pas que ce soit fction bloquante)
    tcgetattr(STDIN_FILENO, &tios); //lit la struct "termios" de l'entrée standard.
    old_c_lflag = tios.c_lflag; // sauve l'ancien flag

    //passe en mode de saisie non canonique
    //(lecture d'1 caractère à la fois par défaut, car MIN=1 et TIME=0)
    tios.c_lflag &= ~ICANON;
    tcsetattr(STDIN_FILENO, TCSANOW, &tios);

    HIDE_CUR();
    return 0;
}

int restaure_terminal(struct termios *prev) {
    //remet les paramètres de départ
    tios.c_lflag = old_c_lflag;
    tcsetattr(STDIN_FILENO, TCSANOW, &tios);

    SHOW_CUR();

    return tcsetattr(fileno(stdin), TCSANOW, prev);
}


//------------------------------------------------------------------------------




